* import to file with existing data\r
* import to empty file\r
* meaning of options etc for v4 files\r
+\r
void printbuf(char* buf, int len)\r
{\r
int i;\r
+ unsigned char * ubuf = (unsigned char *)buf;\r
printf(" 0 1 2 3 4 5 6 7 8 9 A B C D E F\n");\r
printf(" -----------------------------------------------");\r
for(i=0; i<len; i++)\r
{\r
if (((i+1) & 0x0f) == 0x1)\r
printf("\n%2x| ",i/16);\r
- printf("%2x ", (unsigned char)buf[i]);\r
+ printf("%2x ", ubuf[i]);\r
}\r
printf("\n\n");\r
}\r
char use_elevation;\r
char * name;\r
char * desc;\r
+ // This is the MS Map symbol.\r
+ // FIXME Actually, MS Map symbol varies between versions, \r
+ // so this should be an invariant id. \r
+ int symbol;\r
+ char* url;\r
+ char* urlname;\r
// more later\r
} tag_gpxpt;\r
\r
integrate parts into single C/C++ exe (except istorage)\r
9-11-2003 fixed invalid gpx.\r
10-11-2003 gpx import working for routes/tracks to s&t annotation lines.\r
-13-11-2003 export as pcx5 for import into Garmin MapSource\r
+13-11-2003 export as pcx5 for import into Garmin MapSource, \r
+ import from Garmin MapSource text export format\r
20-11-2003 substantial cleanup\r
fixed 8byte alignment in properties.c\r
introduced 1byte alignment for journey analysis\r
22-11-2003 explores UDM data\r
28-11-2003 imports pushpins\r
imports lines to v3 annotations (2002+)\r
+ 5-12-2003 imports/exports symbols, with custom GPX symbol names\r
nw->NoteShort=NULL;\r
nw->UdName=NULL;\r
strcpy(nw->garmin_ident, " ");\r
+ nw->RenderData=0;\r
+ nw->RenderData2=0;\r
+ nw->url=NULL;\r
+ nw->urlname=NULL;\r
return nw;\r
}\r
\r
return;\r
free(pp->NoteShort);\r
free(pp->UdName);\r
+ free(pp->url);\r
+ free(pp->urlname);\r
free(pp);\r
}\r
\r
\r
return ppplist;\r
}\r
+\r
+char std_udm1[6] = {18, 0, 0, 0, 0, 0};\r
+char std_udm2[1] = {1};\r
+\r
+void explore_udm_data(struct pushpin_safelist * ppl)\r
+{\r
+ int i;\r
+ struct f_udm0_header * udm0_head=NULL;\r
+ struct f_udm0_header1 * udm0_head1=NULL;\r
+ struct f_udm0_ppin * udm0_ppin=NULL;\r
+ int expected_udm2_len=0;\r
+\r
+ printf("Exploring UDM_Data from UserData\n");\r
+\r
+ // check UDM_Data[1]\r
+ if(ppl->UDM_Data_length[1] != 6)\r
+ printf("Unexpcted UDM_Data[1] length = %d, expected length 6\n", \r
+ ppl->UDM_Data_length[1]);\r
+ else\r
+ for(i=0; i<6; i++)\r
+ if(ppl->UDM_Data[1][i] != std_udm1[i])\r
+ printf("UDM_Data[1][%d]=%#x, normally expect value %#x\n", \r
+ i,\r
+ (unsigned char)(ppl->UDM_Data[1][i]), \r
+ (unsigned char)(std_udm1[i]));\r
+ \r
+ // check UDM_Data[2]\r
+ if(ppl->UDM_Data_length[2] != 1)\r
+ printf("Unexpcted UDM_Data[2] length = %d, expected length 1\n", \r
+ ppl->UDM_Data_length[2]);\r
+ else\r
+ if(ppl->UDM_Data[2][0] != std_udm2[0])\r
+ printf("UDM_Data[2][0]=%#x, normally expect value %#x\n", \r
+ (unsigned char)ppl->UDM_Data[2][0], \r
+ (unsigned char)(std_udm2[0]));\r
+\r
+ // check UDM_Data[0]\r
+ \r
+ if (ppl->UDM_Data_length[0] < 14)\r
+ {\r
+ printf("UDM_Data[0] is too small to have a valid header\n");\r
+ return;\r
+ }\r
+\r
+ udm0_head = (struct f_udm0_header *)(ppl->UDM_Data[0]);\r
+ printf("There are %d highlighted pushpins\n", udm0_head->c_highlight_recs);\r
+ // list the highlighted udids? Nah.\r
+\r
+ if(udm0_head->sunkn != 0x8001)\r
+ {\r
+ printf("Unexpected f_udm0_header:\n");\r
+ printbuf(ppl->UDM_Data[0], sizeof(struct f_udm0_header));\r
+ }\r
+\r
+ udm0_head1 = (struct f_udm0_header1*)\r
+ (ppl->UDM_Data[0] + sizeof(struct f_udm0_header) \r
+ + 4*(udm0_head->c_highlight_recs));\r
+ \r
+ if( udm0_head1->iunkn != 0)\r
+ printf("Unexpected f_udm0_header1->iunkn=%#x:\n",udm0_head1->iunkn);\r
+\r
+ expected_udm2_len = (14 + 4*(udm0_head->c_highlight_recs) \r
+ + 6*(udm0_head1->c_format_records));\r
+ if(ppl->UDM_Data_length[0] != expected_udm2_len)\r
+ printf("Unexpcted UDM_Data[0] length = %d, expected length %d for %d indicated format_records\n", \r
+ ppl->UDM_Data_length[0], expected_udm2_len, udm0_head1->c_format_records);\r
+ else\r
+ {\r
+ udm0_ppin = (struct f_udm0_ppin *)(ppl->UDM_Data[0] + 14 + 4*(udm0_head->c_highlight_recs) );\r
+ // size has already been verified as (14 + 6 * udm0_head->c_format_records)\r
+ for(i=0; i<(udm0_head1->c_format_records); i++)\r
+ printf("udm0 ppin_rec[%d] has udid=%d, format=%#x, zorder=%d\n",\r
+ i, \r
+ udm0_ppin[i].ppin_udid, \r
+ udm0_ppin[i].format, \r
+ udm0_ppin[i].zorder);\r
+ }\r
+\r
+}
\ No newline at end of file
extern "C" {\r
#endif\r
\r
+// The structures in UserData/UDM_Data for UDMId=0\r
+typedef struct f_udm0_header\r
+{\r
+ unsigned short int sunkn; // normally 0x8001\r
+ int c_highlight_recs; \r
+} tag_f_udm0_header;\r
+// then c_highlight_recs ints with udid of highlighted ppin\r
+typedef struct f_udm0_header1\r
+{\r
+ int iunkn; // normally 0, probably indicates some array length to mess everything up\r
+ int c_format_records;\r
+} tag_f_udm0_header1;\r
+// then c_format_records of these:\r
+typedef struct f_udm0_ppin\r
+{\r
+ int ppin_udid;\r
+ // 1 = show name + info\r
+ // (no record if name not shown?)\r
+ // 3 = show name\r
+ // 4 = upper left\r
+ // 8 = upper right\r
+ // 12 = lower left\r
+ // 16 = lower right\r
+ unsigned char format; \r
+ unsigned char zorder;\r
+} tag_f_udm0_ppin;\r
+\r
typedef struct pushpin_safelist\r
{\r
struct pushpin ** pushpin_list;\r
int SetId;\r
long Grid;\r
long Precision;\r
+ int RenderData;\r
+ // only in mappoint?\r
+ int RenderData2;\r
// dword RenderData;\r
-// byte MatchId;\r
-// long MOBBId;\r
+ // 1 = by hand\r
+ // 2 = from file?\r
+ // 4 = not matched?\r
+ short int MatchId;\r
+ long MOBBId;\r
// long SourceUdId;\r
// bool IsTerritory;\r
//\r
// shouldn't include these 3 here because they are not part of the native pushpin definition\r
double lat;\r
double lon;\r
- // 1 = by hand\r
- // 2 = from file?\r
- // 4 = not matched?\r
- short int MatchId;\r
- long MOBBId;\r
char garmin_ident[7];\r
+ char* url;\r
+ char* urlname;\r
} tag_pushpin;\r
\r
\r
struct point grid2latlon(long grid, long precision);\r
struct grid_point latlon2grid(double lat, double lon);\r
\r
+void explore_udm_data(struct pushpin_safelist * ppl);\r
+\r
#ifdef __cplusplus\r
}\r
#endif\r
return vt_val;\r
};\r
\r
-void variant2val(VARIANT vt_val, unsigned short fieldtype, void* stor_var)\r
+void variant2val(VARIANT vt_val, unsigned short fieldtype, void* stor_var, int expected_buf_length)\r
{\r
char* shortstr=NULL;\r
long lbound;\r
// should be a short?\r
char array_val=0;\r
\r
- if ((vt_val.vt == fieldtype) || ( (fieldtype==VT_BSTR) && (vt_val.vt==VT_NULL)))\r
+ if ((vt_val.vt == fieldtype) || ( (fieldtype==VT_BSTR) && (vt_val.vt==VT_NULL))\r
+ || ( (fieldtype==(VT_ARRAY | VT_UI1)) && (vt_val.vt==VT_NULL)) )\r
{\r
switch (vt_val.vt)\r
{\r
break;\r
\r
case VT_NULL:\r
+ // FIXME should return NULL here and hande the nulls elsewhere\r
// expected string, this is null \r
// so return empty string\r
shortstr = (char*)xmalloc(1);\r
{\r
printf("got safe array of short ints, with %d dimensions and bounds %d:%d\n", \r
SafeArrayGetDim(vt_val.parray), lbound, ubound);\r
- printf("Sadly, I was expecting 1 dimention and lower bound of zero, so I will ignore this array.\n");\r
+ printf("Sadly, I was expecting 1 dimension and lower bound of zero, so I will ignore this array.\n");\r
break;\r
}\r
+\r
+ if (ubound+1 != expected_buf_length)\r
+ {\r
+ printf("Error reading VT_ARRAY: expected length %d but array has length %d\n",\r
+ expected_buf_length, ubound);\r
+ //return;\r
+ }\r
for(elmt=lbound; elmt<ubound+1; elmt++)\r
{\r
SafeArrayGetElement(vt_val.parray, &elmt, &array_val);\r
- //printf("array(%d)=%d\n", elmt, array_val);\r
- ((char*)stor_var)[elmt-lbound]=array_val;\r
+ if (ubound+1 == expected_buf_length)\r
+ ((char*)stor_var)[elmt-lbound]=array_val;\r
+ else\r
+ printf("array(%d)=%d\n", elmt, array_val);\r
}\r
//debug_pause();\r
break;\r
struct pushpin_safelist * ppplist = pushpin_safelist_new();\r
// number of pushpins to allocate pointer-array storage for, this is incremented as needed\r
int ppin_list_alloc_size=100;\r
+ int val_type=0;\r
char * ppin_sql = NULL;\r
char * UDM_sql = NULL;\r
+ char RenderData_buf[4]="";\r
+ int RenderData_len=0;\r
\r
ppplist->pushpin_list = (struct pushpin **)xmalloc(ppin_list_alloc_size*sizeof(struct pushpin *));\r
\r
if (opts.st_version_num<9)\r
- ppin_sql = "SELECT UD_Secondary.UdId, UD_Secondary.UdName, UD_Secondary.NoteShort, UD_Secondary.NoteLong, UD_Main.Grid, UD_Main.Precision, UD_Main.MatchId, UD_Main.MOBBId FROM UD_Main INNER JOIN UD_Secondary ON UD_Main.UdId = UD_Secondary.UdId";\r
+ ppin_sql = "SELECT UD_Secondary.UdId, UD_Secondary.UdName, UD_Secondary.NoteShort, UD_Secondary.NoteLong, UD_Main.Grid, UD_Main.Precision, UD_Main.RenderData, UD_Main.MatchId, UD_Main.MOBBId FROM UD_Main INNER JOIN UD_Secondary ON UD_Main.UdId = UD_Secondary.UdId";\r
else\r
- ppin_sql = "SELECT UdId, UdName, NoteShort, NoteLong, Grid, Precision, MatchId, MOBBId FROM UD_Main";\r
+ ppin_sql = "SELECT UdId, UdName, NoteShort, NoteLong, Grid, Precision, RenderData, MatchId, MOBBId FROM UD_Main";\r
\r
try \r
{\r
{\r
ppin = pushpin_new();\r
\r
- variant2val(rs->Fields->GetItem("UdId")->Value, VT_I4, &(ppin->UdId));\r
- variant2val(rs->Fields->GetItem("UdName")->Value, VT_BSTR,&(ppin->UdName));\r
- variant2val(rs->Fields->GetItem("Grid")->Value, VT_I4, &(ppin->Grid));\r
- variant2val(rs->Fields->GetItem("Precision")->Value,VT_I4, &(ppin->Precision));\r
- variant2val(rs->Fields->GetItem("NoteShort")->Value,VT_BSTR,&(ppin->NoteShort));\r
- variant2val(rs->Fields->GetItem("MatchId")->Value, VT_I2, &(ppin->MatchId));\r
- variant2val(rs->Fields->GetItem("MOBBId")->Value, VT_I4, &(ppin->MOBBId));\r
+ variant2val(rs->Fields->GetItem("UdId")->Value, VT_I4, &(ppin->UdId), 0);\r
+ variant2val(rs->Fields->GetItem("UdName")->Value, VT_BSTR,&(ppin->UdName), 0);\r
+ variant2val(rs->Fields->GetItem("Grid")->Value, VT_I4, &(ppin->Grid), 0);\r
+ variant2val(rs->Fields->GetItem("Precision")->Value,VT_I4, &(ppin->Precision), 0);\r
+ variant2val(rs->Fields->GetItem("NoteShort")->Value,VT_BSTR,&(ppin->NoteShort), 0);\r
+\r
+ RenderData_len = rs->Fields->GetItem("RenderData")->ActualSize;\r
+ val_type = rs->Fields->GetItem("RenderData")->Value.vt;\r
+ if(val_type!=VT_NULL)\r
+ {\r
+ if (RenderData_len==4)\r
+ {\r
+ variant2val(rs->Fields->GetItem("RenderData")->Value,(VT_ARRAY | VT_UI1), RenderData_buf, RenderData_len);\r
+ ppin->RenderData = *(int*)RenderData_buf;\r
+ //printf("got pushpin symbol %#x=%d\n", ppin->RenderData, ppin->RenderData);\r
+ }\r
+ else if (RenderData_len==8)\r
+ {\r
+ variant2val(rs->Fields->GetItem("RenderData")->Value,(VT_ARRAY | VT_UI1), RenderData_buf, RenderData_len);\r
+ ppin->RenderData = *(int*)RenderData_buf;\r
+ //printf("got pushpin symbol %#x=%d\n", ppin->RenderData, ppin->RenderData);\r
+ ppin->RenderData2 = *(int*)(RenderData_buf+4);\r
+ if(ppin->RenderData2 != 0)\r
+ {\r
+ printf("got pushpin symbol %#x=%d\n", ppin->RenderData, ppin->RenderData);\r
+ printf("Got pushpin symbol part2 %#x=%d\n", ppin->RenderData2, ppin->RenderData2);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ printf("Unexpected RenderData_len=%d\n", RenderData_len);\r
+ variant2val(rs->Fields->GetItem("RenderData")->Value,(VT_ARRAY | VT_UI1), RenderData_buf, RenderData_len);\r
+ printbuf(RenderData_buf, RenderData_len);\r
+ }\r
+ }\r
+\r
+ variant2val(rs->Fields->GetItem("MatchId")->Value, VT_I2, &(ppin->MatchId), 0);\r
+ variant2val(rs->Fields->GetItem("MOBBId")->Value, VT_I4, &(ppin->MOBBId), 0);\r
\r
str2ascii(ppin->UdName);\r
str2ascii(ppin->NoteShort);\r
hr = rs->MoveNext();\r
}\r
hr = rs->Close();\r
+ ppplist->num_pushpins=ppinnum;\r
\r
// *************\r
// read UDM_Data\r
// *************\r
\r
- if (opts.explore_flag)\r
+ // always read udm data now\r
+ //if (opts.explore_flag)\r
{\r
UDM_sql = "Select UdmDataId, UdmData from UDM_Data";\r
\r
\r
while ((rs->adoEOF == FALSE))\r
{\r
- variant2val(rs->Fields->GetItem("UdmDataId")->Value, VT_I4, &UdmDataId);\r
+ variant2val(rs->Fields->GetItem("UdmDataId")->Value, VT_I4, &UdmDataId, 0);\r
if ( (UdmDataId<0) || (UdmDataId>3) )\r
{\r
printf("*** Unexpected UdmDataId=%d\n", UdmDataId);\r
\r
ppplist->UDM_Data_length[UdmDataId] = rs->Fields->GetItem("UdmData")->ActualSize; \r
ppplist->UDM_Data[UdmDataId]=(char*)xmalloc(ppplist->UDM_Data_length[UdmDataId]);\r
- variant2val(rs->Fields->GetItem("UdmData")->Value, VT_ARRAY | VT_UI1, ppplist->UDM_Data[UdmDataId]);\r
+ variant2val(rs->Fields->GetItem("UdmData")->Value, VT_ARRAY | VT_UI1, ppplist->UDM_Data[UdmDataId], ppplist->UDM_Data_length[UdmDataId] );\r
\r
printf("In UDM_Data table, for UdId=%d got %d bytes of data\n",\r
UdmDataId, ppplist->UDM_Data_length[UdmDataId]);\r
- printbuf(ppplist->UDM_Data[UdmDataId], ppplist->UDM_Data_length[UdmDataId]);\r
+ \r
+ if (opts.explore_flag)\r
+ {\r
+ printbuf(ppplist->UDM_Data[UdmDataId], ppplist->UDM_Data_length[UdmDataId]);\r
+ }\r
\r
hr = rs->MoveNext();\r
}\r
hr = rs->Close();\r
+\r
+ if (opts.explore_flag)\r
+ explore_udm_data(ppplist);\r
+\r
}\r
\r
rs = NULL;\r
} \r
\r
if (opts.verbose_flag > 1)\r
- printf("Read %d pushpins from %s.\n", ppinnum, ppin_file_name);\r
+ printf("Read %d pushpins from %s.\n", ppplist->num_pushpins, ppin_file_name);\r
\r
- ppplist->num_pushpins=ppinnum;\r
return ppplist;\r
}\r
\r
ADODB::adLockOptimistic, \r
-1 );\r
\r
- variant2val(rs->Fields->GetItem("DbVersion")->Value, VT_I2, &DbVersion);\r
- variant2val(rs->Fields->GetItem("LastSetId")->Value, VT_I4, &LastSetId);\r
- variant2val(rs->Fields->GetItem("LastUserDataId")->Value, VT_I4, &LastUserDataId);\r
+ variant2val(rs->Fields->GetItem("DbVersion")->Value, VT_I2, &DbVersion, 0);\r
+ variant2val(rs->Fields->GetItem("LastSetId")->Value, VT_I4, &LastSetId, 0);\r
+ variant2val(rs->Fields->GetItem("LastUserDataId")->Value, VT_I4, &LastUserDataId, 0);\r
\r
printf("Got DbVersion=%d, LastSetId=%d and LastUserDataId=%d\n", DbVersion, LastSetId, LastUserDataId);\r
\r
\r
if (opts.st_version_num<9)\r
{\r
- sql = "Select UdId, SetId, Grid, Precision, MatchId, MOBBId, SourceUdId from UD_Main";\r
+ sql = "Select UdId, SetId, Grid, Precision, RenderData, MatchId, MOBBId, SourceUdId from UD_Main";\r
sql2 = "Select UdId, NoteTypeId, GeocodeHierarchy, GeocodeContext, UdName, NoteShort, NoteLong from UD_Secondary";\r
hr = rs->Open(sql, \r
cnstr, \r
}\r
else\r
{\r
- sql = "Select UdId, SetId, Grid, Precision, MatchId, MOBBId, SourceUdId, NoteTypeId, GeocodeHierarchy, GeocodeContext, UdName, NoteShort, NoteLong from UD_Main";\r
+ sql = "Select UdId, SetId, Grid, Precision, RenderData, MatchId, MOBBId, SourceUdId, NoteTypeId, GeocodeHierarchy, GeocodeContext, UdName, NoteShort, NoteLong from UD_Main";\r
// maybe we have to do this later, when rs is set?\r
hr = rs->Open(sql, \r
cnstr, \r
rs->Fields->GetItem("Grid" )->Value = val2variant(VT_I4, &(gridpt.grid));\r
rs->Fields->GetItem("Precision" )->Value = val2variant(VT_I4, &(gridpt.precision));\r
rs->Fields->GetItem("MatchId" )->Value = val2variant(VT_I2, &sitwo);\r
+ // This is stored in the DB as binary type, \r
+ // but hopefully it should be ok to write as int.\r
+ // FIXME - Potential problem: \r
+ // This field has longer maximum width in newer MAP versions.\r
+ // Width 32 (AR2001), 64 (MP2002), 128 (AR2003)\r
+\r
+ if(gpt->symbol != 0)\r
+ rs->Fields->GetItem("RenderData" )->Value = val2variant(VT_I4, &(gpt->symbol));\r
rs->Fields->GetItem("MOBBId" )->Value = val2variant(VT_I4, &lzero);\r
rs->Fields->GetItem("SourceUdId")->Value = val2variant(VT_I4, &lzero);\r
\r
"trkpt",\r
"name",\r
"desc",\r
- "src"\r
+ "src",\r
+ "sym",\r
+ "type",\r
+ "url",\r
+ "urlname"\r
};\r
\r
struct gpxpt * gpxpt_new()\r
nw->lon=0;\r
nw->elevation=0;\r
nw->use_elevation=0;\r
+ nw->symbol=0;\r
+ nw->url=NULL;\r
+ nw->urlname=NULL;\r
return nw;\r
}\r
\r
return;\r
free(pt->name);\r
free(pt->desc);\r
+ free(pt->url);\r
+ free(pt->urlname);\r
free(pt);\r
}\r
\r
struct gpxpt * gpxpt_copy(struct gpxpt * otherpt)\r
{\r
struct gpxpt * nw = (struct gpxpt *)xmalloc(sizeof(struct gpxpt));\r
- nw->name=xmalloc(strlen(otherpt->name)+1);\r
- strcpy(nw->name, otherpt->name);\r
- nw->desc=xmalloc(strlen(otherpt->desc)+1);\r
- strcpy(nw->desc, otherpt->desc);\r
+ nw->name = _strdup(otherpt->name);\r
+ nw->desc = _strdup(otherpt->desc);\r
nw->lat=otherpt->lat;\r
nw->lon=otherpt->lon;\r
nw->elevation=otherpt->elevation;\r
nw->use_elevation=otherpt->use_elevation;\r
+ nw->symbol = otherpt->symbol;\r
+ nw->url = _strdup(otherpt->url);\r
+ nw->urlname = _strdup(otherpt->urlname);\r
return nw;\r
}\r
\r
desc[cdata_length]=0;\r
cdata=NULL;\r
cdata_length=0;\r
- str2ascii(desc);\r
switch (current_main_element)\r
{\r
case GPX_ELEM_TYPE_WPT:\r
{\r
}\r
\r
-#define GPX_NUM_ELEM_HANDLERS 10\r
+void startsym(void *userData, const char *name, const char **atts)\r
+{\r
+}\r
+\r
+void endsym(void *userData, const char *name)\r
+{\r
+ struct gpx_data * dat = (struct gpx_data *)userData;\r
+ char* sym_str = xrealloc(cdata, cdata_length+1);\r
+ int sym_num=0;\r
+ int read;\r
+\r
+ sym_str[cdata_length]=0;\r
+ cdata=NULL;\r
+ cdata_length=0;\r
+\r
+\r
+ // We need to convert the name of the symbol sym_str from GPX \r
+ // into a numeric symbol number for MS Map.\r
+ // For now we just accept MS Map Symbol n\r
+\r
+/* if (strncmp(sym_str, "MS Map Symbol", 13)!=0)\r
+ {\r
+ free(sym_str);\r
+ return;\r
+ }\r
+*/ \r
+ read=sscanf(sym_str, "MS Map Symbol %d", &sym_num);\r
+\r
+ if( (read==1) && (sym_num>0) )\r
+ printf("Translated symbol name %s as symbol number %d\n", sym_str, sym_num);\r
+ else\r
+ {\r
+ printf("Couldn't translate symbol name %s to a symbol number\n", sym_str);\r
+ free(sym_str);\r
+ return;\r
+ }\r
+\r
+ switch (current_main_element)\r
+ {\r
+ case GPX_ELEM_TYPE_WPT:\r
+ // We may have already set the symbol from <type>,\r
+ // which over-rides the symbol.\r
+ // Fixme this override should eb an option, not the default.\r
+ if(dat->wpt_list[dat->wpt_list_count-1]->symbol == 0)\r
+ dat->wpt_list[dat->wpt_list_count-1]->symbol=sym_num;\r
+ break;\r
+ case GPX_ELEM_TYPE_RTE:\r
+ case GPX_ELEM_TYPE_RTEPT:\r
+ case GPX_ELEM_TYPE_TRK:\r
+ case GPX_ELEM_TYPE_TRKSEG:\r
+ case GPX_ELEM_TYPE_TRKPT:\r
+ default:\r
+ break;\r
+ }\r
+\r
+ free(sym_str);\r
+}\r
+\r
+void starttype(void *userData, const char *name, const char **atts)\r
+{\r
+}\r
+\r
+void endtype(void *userData, const char *name)\r
+{\r
+ struct gpx_data * dat = (struct gpx_data *)userData;\r
+ char* type_str = xrealloc(cdata, cdata_length+1);\r
+ int sym_num=0;\r
+\r
+ type_str[cdata_length]=0;\r
+ cdata=NULL;\r
+ cdata_length=0;\r
+\r
+ if(strcmp(type_str, "Geocache|Virtual Cache")==0)\r
+ sym_num=68; // balloon\r
+ else if(strcmp(type_str, "Geocache|Traditional Cache")==0)\r
+ sym_num=55; // small purple or green triange\r
+ else if(strcmp(type_str, "Geocache|Multi-Cache")==0)\r
+ sym_num=107; // three flags\r
+ //sym_num=132; // traffic-light\r
+ else if(strcmp(type_str, "Geocache|Unknown Cache")==0)\r
+ sym_num=254; // question-mark\r
+ else if(strcmp(type_str, "Geocache|Micro Cache")==0)\r
+ sym_num=65;\r
+ \r
+ switch (current_main_element)\r
+ {\r
+ case GPX_ELEM_TYPE_WPT:\r
+ if(sym_num != 0)\r
+ dat->wpt_list[dat->wpt_list_count-1]->symbol=sym_num;\r
+ break;\r
+ case GPX_ELEM_TYPE_RTE:\r
+ case GPX_ELEM_TYPE_RTEPT:\r
+ case GPX_ELEM_TYPE_TRK:\r
+ case GPX_ELEM_TYPE_TRKSEG:\r
+ case GPX_ELEM_TYPE_TRKPT:\r
+ default:\r
+ break;\r
+ }\r
+\r
+ free(type_str);\r
+}\r
+\r
+void starturl(void *userData, const char *name, const char **atts)\r
+{\r
+}\r
+\r
+void endurl(void *userData, const char *name)\r
+{\r
+ struct gpx_data * dat = (struct gpx_data *)userData;\r
+ char* url_str = xrealloc(cdata, cdata_length+1);\r
+\r
+ url_str[cdata_length]=0;\r
+ cdata=NULL;\r
+ cdata_length=0;\r
+\r
+ switch (current_main_element)\r
+ {\r
+ case GPX_ELEM_TYPE_WPT:\r
+ dat->wpt_list[dat->wpt_list_count-1]->url=url_str;\r
+ break;\r
+ case GPX_ELEM_TYPE_RTE:\r
+ case GPX_ELEM_TYPE_RTEPT:\r
+ case GPX_ELEM_TYPE_TRK:\r
+ case GPX_ELEM_TYPE_TRKSEG:\r
+ case GPX_ELEM_TYPE_TRKPT:\r
+ default:\r
+ break;\r
+ free(url_str);\r
+ }\r
+\r
+}\r
+\r
+void starturlname(void *userData, const char *name, const char **atts)\r
+{\r
+}\r
+\r
+void endurlname(void *userData, const char *name)\r
+{\r
+ struct gpx_data * dat = (struct gpx_data *)userData;\r
+ char* url_str = xrealloc(cdata, cdata_length+1);\r
+\r
+ url_str[cdata_length]=0;\r
+ cdata=NULL;\r
+ cdata_length=0;\r
+\r
+ switch (current_main_element)\r
+ {\r
+ case GPX_ELEM_TYPE_WPT:\r
+ dat->wpt_list[dat->wpt_list_count-1]->urlname=url_str;\r
+ break;\r
+ case GPX_ELEM_TYPE_RTE:\r
+ case GPX_ELEM_TYPE_RTEPT:\r
+ case GPX_ELEM_TYPE_TRK:\r
+ case GPX_ELEM_TYPE_TRKSEG:\r
+ case GPX_ELEM_TYPE_TRKPT:\r
+ default:\r
+ break;\r
+ free(url_str);\r
+ }\r
+\r
+}\r
+\r
+#define GPX_NUM_ELEM_HANDLERS 14\r
\r
gpx_elm_start_handler gpx_start_elm_handler[] =\r
{\r
&starttrkpt,\r
&startname,\r
&startdesc,\r
- &startsrc\r
+ &startsrc,\r
+ &startsym,\r
+ &starttype,\r
+ &starturl,\r
+ &starturlname\r
};\r
\r
gpx_elm_end_handler gpx_end_elm_handler[] =\r
&endtrkpt,\r
&endname,\r
&enddesc,\r
- &endsrc\r
+ &endsrc,\r
+ &endsym,\r
+ &endtype,\r
+ &endurl,\r
+ &endurlname\r
};\r
\r
-\r
int get_gpx_type_ndx(const char* type_name)\r
{\r
int i;\r
char * str2ascii(char* str)\r
{\r
int i;\r
- int len=strlen(str);\r
+ int len;\r
unsigned char * ustr = (unsigned char*)str;\r
+\r
+ if(str==NULL)\r
+ return str;\r
+\r
+ len=strlen(str);\r
for(i=0; i<len; i++)\r
// FIXME saxcount complains that 0x1c is an invalid character, what else??\r
if ( (ustr[i]>127) || (ustr[i]==0x1c) )\r
char * strappend(char* str1, char* str2)\r
// create a new string\r
{\r
- int len1=strlen(str1);\r
- int len2=strlen(str2);\r
- char* nw = (char*)xmalloc(len1 + len2 +1);\r
- strcpy(nw, str1);\r
- strcpy(nw+len1, str2);\r
+ int len1;\r
+ int len2;\r
+ char* nw;\r
+ \r
+ if (str1==NULL)\r
+ len1=0;\r
+ else\r
+ len1=strlen(str1);\r
+\r
+ if (str2==NULL)\r
+ len2=0;\r
+ else\r
+ len2=strlen(str2);\r
+\r
+ nw = (char*)xmalloc(len1 + len2 +1);\r
+\r
+ if (str1 != NULL)\r
+ strcpy(nw, str1);\r
+ if (str2 != NULL)\r
+ strcpy(nw+len1, str2);\r
+ \r
+ //just in case len1 + len2 =0\r
+ nw[len1 + len2]=0;\r
+\r
return nw;\r
}\r
\r
# Begin Source File\r
\r
SOURCE=.\annotations.c\r
-\r
-!IF "$(CFG)" == "st2gpx - Win32 Release"\r
-\r
-!ELSEIF "$(CFG)" == "st2gpx - Win32 Debug"\r
-\r
-# SUBTRACT CPP /FA<none>\r
-\r
-!ENDIF \r
-\r
# End Source File\r
# Begin Source File\r
\r
# End Source File\r
# Begin Source File\r
\r
-SOURCE=.\msado15.tlh\r
-# End Source File\r
-# Begin Source File\r
-\r
-SOURCE=.\msado15.tli\r
-# End Source File\r
-# Begin Source File\r
-\r
SOURCE=.\ToDo.txt\r
# End Source File\r
# End Target\r
extern "C" {
#endif
-//#define MEMCHK
-//#define DEBUG_STDOUT
#ifdef _DEBUG
+\r
+#define MEMCHK\r
+#define DEBUG_STDOUT\r
+\r
#define _CRTDBG_MAP_ALLOC
#define SET_CRT_DEBUG_FIELD(a) _CrtSetDbgFlag((a) | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG))
#define CLEAR_CRT_DEBUG_FIELD(a) _CrtSetDbgFlag(~(a) & _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG))
extern struct st2gpx_options opts;
void * xmalloc(size_t size);
void * xrealloc(void* ptr, size_t size);
-char * str2ascii(char* str);
+char * str2ascii(char* str);\r
+char * strappend(char* str1, char* str2);
int readbytes(FILE* file, char* buf, int bytes2read);
//nannol.c
struct annotations * merge_gpx_annot(struct annotations * annots, struct gpx_data* all_gpx);
}\r
}\r
\r
-void gpx_write_point(FILE* gpx_out_file, struct gpxpt * pt, int pt_type, char* opt_elms)\r
-// FIXEM do <name> from pt, not from opt_elms\r
-// FIXME same for other atts defined in gpxpt\r
+void gpx_write_point(FILE* gpx_out_file, struct gpxpt * pt, int pt_type)\r
+// FIXME write other atts defined in gpxpt\r
{\r
if (gpx_out_file!=NULL)\r
{\r
fprintf(gpx_out_file, "\t\t");\r
else if (pt_type == GPX_RTEPT)\r
fprintf(gpx_out_file, "\t");\r
- fprintf(gpx_out_file, "\t<%s lat=\"%f\" lon=\"%f\">%s</%s>\n",\r
- gpxptypelabel[pt_type], pt->lat, pt->lon,\r
- opt_elms, gpxptypelabel[pt_type]);\r
+ fprintf(gpx_out_file, "\t<%s lat=\"%f\" lon=\"%f\">", \r
+ gpxptypelabel[pt_type], pt->lat, pt->lon);\r
+ if( (pt->name != NULL) && (strlen(pt->name)>0) )\r
+ fprintf(gpx_out_file, "<name><![CDATA[%s]]></name>", pt->name);\r
+ if( (pt->desc != NULL) && (strlen(pt->desc)>0) )\r
+ fprintf(gpx_out_file, "<desc><![CDATA[%s]]></desc>", pt->desc);\r
+ // FIXME do some translation here?\r
+ if(pt->symbol != 0)\r
+ fprintf(gpx_out_file, "<sym>MS Map Symbol %d</sym>", pt->symbol);\r
+ if( (pt->url != NULL) && (strlen(pt->url)>0) )\r
+ fprintf(gpx_out_file, "<desc><![CDATA[%s]]></desc>", pt->url);\r
+ if( (pt->urlname != NULL) && (strlen(pt->urlname)>0) )\r
+ fprintf(gpx_out_file, "<desc><![CDATA[%s]]></desc>", pt->urlname);\r
+ fprintf(gpx_out_file, "</%s>\n", gpxptypelabel[pt_type]);\r
}\r
}\r
\r
void gpx_write_jour_point(FILE* gpx_out_file, struct journey * jour, struct jour_rtept * wpt)\r
{\r
struct gpxpt * pt = gpxpt_new();\r
- char* opt_elms;\r
- int optlen;\r
+// char* opt_elms;\r
+// int optlen;\r
struct f_jour_pt_head * f_wpt_head;\r
\r
if (gpx_out_file==NULL)\r
f_wpt_head = (struct f_jour_pt_head *)(jour->buf + (wpt->pthead_os));\r
pt->lat=scaled2deg(f_wpt_head->scaled_lat);\r
pt->lon=scaled2deg(f_wpt_head->scaled_lon);\r
- optlen = f_wpt_head->cbtext1 + 60;\r
- opt_elms = (char*)xmalloc(optlen);\r
+// optlen = f_wpt_head->cbtext1 + 60;\r
+// opt_elms = (char*)xmalloc(optlen);\r
//FIXME use str2ascii??\r
- sprintf(opt_elms, "<name><![CDATA[%s]]></name>", wpt->text1);\r
+// sprintf(opt_elms, "<name><![CDATA[%s]]></name>", wpt->text1);\r
+ pt->name=_strdup(wpt->text1);\r
\r
}\r
else\r
{\r
- optlen = strlen(wpt->pushpin->UdName) + strlen(wpt->pushpin->NoteShort) + 60;\r
- opt_elms = (char*)xmalloc(optlen);\r
+// optlen = strlen(wpt->pushpin->UdName) + strlen(wpt->pushpin->NoteShort) + 60;\r
+// opt_elms = (char*)xmalloc(optlen);\r
\r
- sprintf(opt_elms, "<name><![CDATA[%s]]></name><desc><![CDATA[%s]]></desc>",\r
- wpt->pushpin->UdName, wpt->pushpin->NoteShort);\r
+// sprintf(opt_elms, "<name><![CDATA[%s]]></name><desc><![CDATA[%s]]></desc>",\r
+// wpt->pushpin->UdName, wpt->pushpin->NoteShort);\r
+ pt->name=_strdup(wpt->text1);\r
+ pt->desc=_strdup(wpt->pushpin->NoteShort);\r
\r
pt->lat = wpt->pushpin->lat;\r
pt->lon = wpt->pushpin->lon;\r
}\r
\r
- gpx_write_point(gpx_out_file, pt, GPX_RTEPT, opt_elms);\r
+ gpx_write_point(gpx_out_file, pt, GPX_RTEPT);\r
\r
gpxpt_delete(pt);\r
- free(opt_elms);\r
+// free(opt_elms);\r
}\r
\r
void gpx_write_jour_header(FILE* gpx_out_file)\r
{\r
int i;\r
struct gpxpt * pt=NULL;\r
- char* opt_elms;\r
- int optlen;\r
+// char* opt_elms;\r
+// int optlen;\r
\r
if ((gpx_out_file==NULL) || (ppplist==NULL))\r
return;\r
if (ppplist->pushpin_list[i]==NULL)\r
break;\r
\r
- optlen = strlen(ppplist->pushpin_list[i]->UdName)\r
- + strlen(ppplist->pushpin_list[i]->NoteShort) + 60;\r
- opt_elms = (char*)xmalloc(optlen);\r
+// optlen = strlen(ppplist->pushpin_list[i]->UdName)\r
+// + strlen(ppplist->pushpin_list[i]->NoteShort) + 60;\r
+// opt_elms = (char*)xmalloc(optlen);\r
\r
- sprintf(opt_elms, "<name><![CDATA[%s]]></name><desc><![CDATA[%s]]></desc>",\r
- ppplist->pushpin_list[i]->UdName, ppplist->pushpin_list[i]->NoteShort);\r
+// sprintf(opt_elms, "<name><![CDATA[%s]]></name><desc><![CDATA[%s]]></desc>",\r
+// ppplist->pushpin_list[i]->UdName, ppplist->pushpin_list[i]->NoteShort);\r
+\r
+ pt->name = _strdup(ppplist->pushpin_list[i]->UdName);\r
+ pt->desc = _strdup(ppplist->pushpin_list[i]->NoteShort);\r
\r
pt->lat = ppplist->pushpin_list[i]->lat;\r
pt->lon = ppplist->pushpin_list[i]->lon;\r
-\r
- gpx_write_point(gpx_out_file, pt, GPX_WPT, opt_elms);\r
- free(opt_elms);\r
+ // FIXEM some translation is needed here\r
+ pt->symbol = ppplist->pushpin_list[i]->RenderData;\r
+\r
+ gpx_write_point(gpx_out_file, pt, GPX_WPT);\r
+// free(opt_elms);\r
+ free(pt->name);\r
+ pt->name=NULL;\r
+ free(pt->desc);\r
+ pt->desc=NULL;\r
}\r
fprintf(gpx_out_file, "\n");\r
gpxpt_delete(pt);\r
}\r
\r
-void gpx_write_annot_rec(FILE* gpx_out_file, const struct annot_rec * rec)\r
+void gpx_write_annot_rec(FILE* gpx_out_file, struct annot_rec * rec)\r
{\r
int pt_type;\r
int p;\r
- char opt_elms[200];\r
+// char opt_elms[200];\r
struct gpxpt * pt;\r
\r
if ( (gpx_out_file==NULL) || (rec==NULL) )\r
for (p=0; p < rec->line_points; p++)\r
{\r
pt=gpx_get_point(rec->buf + rec->line_offset + 12*p);\r
+ pt->name=(char*)xmalloc(7);\r
if(pt==NULL)\r
{\r
printf("got null pt #%p in annotation %d, skipping more points in this annotation\n",\r
break;\r
}\r
if(opts.use_gpx_route)\r
- sprintf(opt_elms, "<name>rp%04d</name>", p);\r
+ sprintf(pt->name, "rp%04d", p);\r
+ //sprintf(opt_elms, "<name>rp%04d</name>", p);\r
else\r
// we need to include a name for trackpoints\r
// for them to be recognised by easygps.\r
- sprintf(opt_elms, "<name>tp%04d</name>", p);\r
- gpx_write_point(gpx_out_file, pt, pt_type, opt_elms);\r
+ sprintf(pt->name, "tp%04d", p);\r
+ //sprintf(opt_elms, "<name>tp%04d</name>", p);\r
+ gpx_write_point(gpx_out_file, pt, pt_type);\r
gpxpt_delete(pt);\r
}\r
\r